#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QDebug>
#include <QThread>

extern "C" {
// 设备
#include<libavdevice/avdevice.h>
// 格式
#include<libavformat/avformat.h>
// 工具库
#include<libavutil/avutil.h>
}

#ifdef Q_OS_WIN
    // 格式名称
    #define FMT_NAME "dshow"
    // 设备名称
    #define DEVICE_NAME "audio=麦克风阵列 (Realtek(R) Audio)"
    // 文件名
    #define FILENAME "D:/out.pcm"
#else
    #define FMT_NAME "avfoundation"
    #define DEVICE_NAME ":0"
    #define FILENAME "/Users/yu/Desktop/out.pcm"
#endif

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow) {
    ui->setupUi(this);
    qDebug() << QThread::currentThread(); // 当前线程
}

MainWindow::~MainWindow() {
    delete ui;
}

void MainWindow::on_audioButton_clicked() {

    qDebug() << QThread::currentThread(); // 当前线程

    AVInputFormat * fmt = av_find_input_format(FMT_NAME);
    if (!fmt) {
        qDebug() << "获取输入格式对象失败" << FMT_NAME;
        return;
    }

    // 格式上下文(将来可以利用上下文操作设备)
    AVFormatContext *ctx = nullptr; // 需要初始化为空

    // 打开设备
    int ret = avformat_open_input(&ctx, DEVICE_NAME, fmt, nullptr);
    if (ret < 0) {
        char errbuf[1024] = {0}; // 用来接收错误信息的数组
        av_strerror(ret, errbuf, sizeof(errbuf));
        qDebug() << "打开设备失败" << errbuf;
        return;
    }

    QFile file(FILENAME);

    // 打开文件
    // WriteOnly:只读模式。如果文件不存在,就创建文件;如果文件存在,就会清空文件内容
    if (!file.open(QFile::WriteOnly)) {
        qDebug() << "文件打开失败" << FILENAME;
        // 关闭设备
        avformat_close_input(&ctx);
        return;
    }

    // 采集的次数
    int count = 50;

    // 数据包
    AVPacket pkt;
    // 不断采集数据
    while (count-- > 0 && av_read_frame(ctx, &pkt) == 0) {
        // 将数据写入文件
        file.write((const char*)pkt.data, pkt.size);
    }

    // 释放资源
    // 关闭文件
    file.close();

    // 关闭设备
    avformat_close_input(&ctx);
}
